#include <stdbool.h>

#include "driver/gpio.h"
#include "driver/uart.h"
#include "PN532_HardwareSerial.hpp"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

namespace idf {

namespace pn532 {

PN532_HardwareSerial::PN532_HardwareSerial(void)
{
    uart_initFlag = 0;
}

void PN532_EN_GPIO(int gpio_num,uint32_t lvl)
{
    gpio_set_direction((gpio_num_t)gpio_num,GPIO_MODE_OUTPUT);
    gpio_set_level((gpio_num_t)gpio_num,lvl);
	vTaskDelay(100 / portTICK_RATE_MS);
}



void PN532_HardwareSerial::Init(void)
{    
    const uart_config_t uart_config = 
    {
    .baud_rate  = PN532_UART_RATE,
    .data_bits  = UART_DATA_8_BITS,
    .parity     = UART_PARITY_DISABLE,
    .stop_bits  = UART_STOP_BITS_1,
    .flow_ctrl  = UART_HW_FLOWCTRL_DISABLE,
    .rx_flow_ctrl_thresh= UART_HW_FLOWCTRL_DISABLE,
    .source_clk = UART_SCLK_APB,
    };  

    if ( uart_initFlag == 1 ) return;
    
	//gpio_reset_pin((gpio_num_t)PN532_PIN_RSTOUT_N);
	//gpio_reset_pin((gpio_num_t)PN532_PIN_IRQ);
    PN532_EN_GPIO(PN532_EN_PIN,0);

    uart_driver_install(PN532_UART_NUM, PN532_UART_RECVBUFFSISE, PN532_UART_SENDBUFFSISE, 0, NULL, 0);
    uart_param_config(PN532_UART_NUM, &uart_config);
    uart_set_pin(PN532_UART_NUM, PN532_TXD, PN532_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

    uart_initFlag = 1;
}

int PN532_HardwareSerial::write(uint8_t ucByte)
{
     return uart_tx_chars(PN532_UART_NUM, (const char *)&ucByte, 1);
}

size_t PN532_HardwareSerial::available(void)
{
    uart_get_buffered_data_len(PN532_UART_NUM, &iRLen);
    return iRLen;
}
uint8_t PN532_HardwareSerial::read(void)
{
    uint8_t ucTemp;
    uart_read_bytes(PN532_UART_NUM, &ucTemp, 1, pdMS_TO_TICKS(10));
    return ucTemp;
}

int PN532_HardwareSerial::sendData(const void *src, size_t size)
{
    return uart_write_bytes(PN532_UART_NUM, src, size);
}
int PN532_HardwareSerial::recvData(void *buf,uint32_t length,uint16_t ms_to_wait)
{
    return  uart_read_bytes(PN532_UART_NUM, buf, length, pdMS_TO_TICKS(ms_to_wait));
}

} // namespace

} // namespace 

